////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "WNCore/inc/WNTypes.h"
#include "WNCore/inc/WNAssert.h"
#include "WNCore/inc/WNMacros.h"
#include "WNMemory/inc/WNMemory.h"
#include "WNStrings/inc/WNStrings.h"
#include "WNScripting/inc/WNScripting.h"

#include <iostream>

using namespace WNStrings;
using namespace WNMemory;

WN_CHAR* getLine(WN_CHAR*_line, WN_UINT32 _sz){
   if (fgets(_line, _sz, stdin)) {
      WN_CHAR *current = WNStrChr(_line, '\n'); /* check for trailing '\n' */

      if (current != WN_NULL) {
         *current =  '\0'; /* overwrite the '\n' with a terminating null */
      }
   }

   return(_line);
}

WN_INT32 testFunc(WN_UINT32 val) {
    WN_PRINTF("\n\n\n%d\n\n\n", val);

    return(1);
}

WN_VOID* sneakymalloc(WN_SIZE_T _sz) {
    WN_VOID* memory = WNMalloc(_sz);

    WN_PRINTF("malloc(%p)%ld\n", memory, _sz);

    return(memory);
}

WN_VOID sneakydelete(WN_VOID* _ptr) {
    WN_PRINTF("free(%p)\n", _ptr);

    WNFree(_ptr);
}

WN_INT32 main(WN_INT32 _argc, WN_CHAR** _argv) {
    WN_CHAR tests[1024];

    if (_argc < 2) {
        WN_PRINTF("Enter Filename >>");

        getLine(tests, 1023);

        return(-1);
    } else {
        WNStrCpy(tests, _argv[1]);
    }
    
    const char* func = (_argc > 2)?_argv[2] : "test";

    WN_SIZE_T scriptingEngineSize = WNScripting::WNGetScriptingEngineSize();
    WN_VOID* loc = WN_STACK_ALLOC(scriptingEngineSize);
    WNScripting::WNScriptingEngine* scriptingEngine = WNScripting::WNCreateScriptingEngine(loc);

    WN_RELEASE_ASSERT(scriptingEngine->Initialize() == WN_TRUE);

    scriptingEngine->AddExternalFunction(reinterpret_cast<WN_VOID*>(&testFunc), WN_FALSE, "WN_INT32", "testFunc", "WN_INT32");
    scriptingEngine->SetFreeFunction(sneakydelete);
    scriptingEngine->SetMallocFunction(sneakymalloc);
    scriptingEngine->SetMemcpyFunction(WNMemCpy);

    std::vector<WNScripting::WNScriptingEngine::WNParameter> params;
    WNScripting::WNScriptingEngine::WNParameter param;
    scriptingEngine->RunFunction(tests, func, params, param);
    std::cout << param.mInt32Val << "\n";

    WNDestroyScriptingEngine(scriptingEngine);
}
